import React, {Component, RefObject} from 'react';
import ReactDOM from 'react-dom';

interface Props {

}

interface State {
  messages: Array<string>;
}

class ScrollList extends React.Component<Props, State> {
  timer: any;
  wrapper: RefObject<HTMLDivElement>;

  constructor(props: Props) {
    super(props);
    this.state = {messages: []};
    this.wrapper = React.createRef();
  }

  componentDidMount() {
    this.timer = setInterval(() => {
      this.setState({
        messages: [`message-${this.state.messages.length}`, ...this.state.messages]
      })
    }, 1000);
  }

  componentWillUnmount() {
    clearInterval(this.timer);
  }

  /*
      getSnapshotBeforeUpdate() 被调用于render之后，可以读取到老的dom。
      它使您的组件可以在可能更改之前从DOM捕获一些信息（例如滚动位置）。
      此生命周期返回的任何值都将作为参数传递给componentDidUpdate()
  */
  getSnapshotBeforeUpdate(prevProps: Readonly<Props>, prevState: Readonly<State>): any | null {
    return this.wrapper.current!.scrollHeight; //返回的就是componentDidUpdate接受到的snapshot参数
  }

  componentDidUpdate(prevProps: Readonly<Props>, prevState: Readonly<State>, snapshot?: any): void {
    this.wrapper.current!.scrollTop = this.wrapper.current!.scrollTop + (this.wrapper.current!.scrollHeight - snapshot);
  }

  render() {
    const style = {
      height: 100
      , with: 200
      , border: '1px solid red'
      , overflow: 'auto'
    };
    return (
      <div style={style} ref={this.wrapper}>
        {
          this.state.messages.map((message: string, index: number) => (
            <div key={index}>{message}</div>
          ))
        }
      </div>
    )
  }
}

ReactDOM.render(<ScrollList/>, document.getElementById('root'))
